package com.sali.netty.handler;

import cn.hutool.json.JSONObject;
import com.sali.constants.CommonConstant;
import com.sali.disruptor.MessageDisruptorService;
import com.sali.statistics.MockMessageStatistics;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @description: Mock客户端报文处理
 * @author: sali
 * @date: 2025/2/22 下午2:00.
 * @version: 1.0
 */
@Slf4j
public class ServerHandle extends SimpleChannelInboundHandler<JSONObject> {

    private MessageDisruptorService messageDisruptorService;

    private AtomicInteger readIdleTimes = new AtomicInteger(0);

    public ServerHandle(MessageDisruptorService messageDisruptorService) {
        this.messageDisruptorService = messageDisruptorService;
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, JSONObject json) throws Exception {
        //读到数据设置为0
        this.readIdleTimes.set(0);

//        log.info("接收到报文信息:{}", json);

        // 发送到消息队列
        messageDisruptorService.getMessageProduction().putData(json);

        MockMessageStatistics.getRecMsgCount().incrementAndGet();
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            IdleStateEvent event = (IdleStateEvent) evt;
            if (IdleState.READER_IDLE.equals(event.state())) {
                readIdleTimes.incrementAndGet();
            }

            if (readIdleTimes.get() > CommonConstant.Netty.READIDLE_COUNT) {
                log.warn("[tcp mock server]读空闲超过{}次,需要检查mock tcp client是否正常！！ IP:{}", CommonConstant.Netty.READIDLE_COUNT, ctx.channel().remoteAddress());
            }
        } else {
            super.userEventTriggered(ctx, evt);
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("mock client已连接到服务端:{}", ctx.channel().remoteAddress());
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("mock client已离开了服务端:{}", ctx.channel().remoteAddress());
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if (cause instanceof IOException) {
            log.warn("exceptionCaught: mock client [{}]和远程断开了连接", ctx.channel().remoteAddress());
        } else {
            log.error("client throw a error:[message:{}]", cause.getMessage(), cause);
        }
        ctx.channel().close();
    }

}
